package com.base


import android.content.Context
import android.content.SharedPreferences
import android.text.TextUtils
import android.util.Log
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKeys
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
import com.google.gson.Gson
import com.net.HttpResponse
import com.net.QueryInterface
import com.orhanobut.logger.AndroidLogAdapter
import com.orhanobut.logger.Logger
import com.somlsis.bean.Device
import com.somlsis.bean.DeviceInfo
import com.somlsis.bean.Upload
import com.somlsis.bean.User
import com.somlsis.bean.UserOverview
import com.somlsis.interf.UploadCallBack
import com.utils.ImageUtils
import okhttp3.Dispatcher
import okhttp3.OkHttpClient
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit


class DataCenter {
    private var user: User? = null
    private var token: String? = null
    private lateinit var okHttpClient: OkHttpClient
    private lateinit var service: QueryInterface
    private lateinit var context: Context
    private lateinit var sharedPreferences: SharedPreferences
    private  var deviceList= ArrayList<Device>()
    private var userOverview: UserOverview? = null

    //声明AMapLocationClient类对象
    private lateinit var mLocationClient: AMapLocationClient

    //声明定位回调监听器
    private val mLocationListener: AMapLocationListener = AMapLocationListener {

        if (it != null) {
            if (it.getErrorCode() == 0) {
                //可在其中解析amapLocation获取相应内容。
            } else {
                //定位失败时，可通过ErrCode（错误码）信息来确定失败的原因，errInfo是错误信息，详见错误码表。
                Log.e(
                    "AmapError", "location Error, ErrCode:"
                            + it.errorCode + ", errInfo:"
                            + it.errorInfo
                );
            }
        }
    }

    //声明AMapLocationClientOption对象
    private lateinit var option: AMapLocationClientOption

    companion object {
        val instance = DataCenterInit.dataCenterInit
    }

    private object DataCenterInit {
        val dataCenterInit = DataCenter()
    }

    fun initOther(context: Context) {
        this.context = context
        sharedPreferences = initSharedPreferences(context)
        initNet()
        initLocation()
        createUserInfo()
        Logger.addLogAdapter(AndroidLogAdapter())
    }

    private fun initSharedPreferences(context: Context): SharedPreferences {
        val masterKeyAlias: String = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)

        return EncryptedSharedPreferences.create(
            "secret_shared_prefs",
            masterKeyAlias,
            context,
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
        )
    }

    private fun initNet() {
        val dispatcher = Dispatcher()
        //自定义上限
        dispatcher.maxRequests = 1000
        //自定义上限
        dispatcher.maxRequestsPerHost = 1000
        okHttpClient = OkHttpClient.Builder()
            .dispatcher(dispatcher)
            .retryOnConnectionFailure(false)
            .addInterceptor(HttpInterceptor())
            .connectTimeout(AppConfig.CONNECT_TIMEOUT, TimeUnit.SECONDS)
            .build()
        service = Retrofit.Builder()
            .baseUrl(AppConfig.DIV_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build().create(QueryInterface::class.java)

    }

    private fun initLocation() {
        AMapLocationClient.updatePrivacyShow(context, true, true)
        AMapLocationClient.updatePrivacyAgree(context, true)
        //初始化定位
        mLocationClient = AMapLocationClient(context)
        //设置定位回调监听
        mLocationClient.setLocationListener(mLocationListener)

        option = AMapLocationClientOption()
        option.locationPurpose = AMapLocationClientOption.AMapLocationPurpose.Sport

        //设置定位模式为AMapLocationMode.Hight_Accuracy，高精度模式。
        option.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
        //设置定位间隔,单位毫秒,默认为2000ms，最低1000ms。
        option.interval = 10000

        //设置是否返回地址信息（默认返回地址信息）
        option.isNeedAddress = false

        //关闭缓存机制
        option.setLocationCacheEnable(false);


        //给定位客户端对象设置定位参数
        mLocationClient.setLocationOption(option)
        //启动定位
        // mLocationClient.startLocation()

    }

    //初始化用户信息 初始化各种
    private fun createUserInfo() {
        var loginJson = sharedPreferences.getString("UserInfo", "")
        if (!TextUtils.isEmpty(loginJson)) {
            user = Gson().fromJson(loginJson, User::class.java)
            user?.let {
                token = it.remember_token
            }
        }
    }

    fun setUser(userBean: User) {
        user = userBean
        saveUser()
    }

    fun getUser(): User? {
        return user
    }

    private fun saveUser() {
        if (user != null) {
            sharedPreferences.edit().apply {
                putString("UserInfo", Gson().toJson(user))
                apply()

            }
        }
    }


    fun getSMSCode(tel: String, key: String, callback: Callback<HttpResponse<String>>) {
        val query = service.getSMSCode(tel, key)
        query.enqueue(callback)
    }

    fun loginForCode(tel: String, code: String, callback: Callback<HttpResponse<User>>) {
        val query = service.loginForCode(tel, AppConfig.KEY_LOGIN, code)
        query.enqueue(callback)
    }

    fun loginForPwd(tel: String, pwd: String, callback: Callback<HttpResponse<User>>) {
        val query = service.loginForPwd(tel, AppConfig.KEY_PWD, pwd)
        query.enqueue(callback)
    }

    fun getUserOverview(callback: Callback<HttpResponse<UserOverview>>) {
        user?.let {
            val query = service.getUserOverview(it.unique)
            query.enqueue(callback)
        }
    }

    fun store(motionData: String, callback: Callback<HttpResponse<String>>) {
        user?.let {
            val query = service.store(it.unique, motionData)
            query.enqueue(callback)
        }
    }

    fun submitFeedback(
        type: String,
        content: String,
        mobile: String,
        pics: ArrayList<String>,
        callback: Callback<HttpResponse<String>>
    ) {
        user?.let {
            val query = service.submitFeedback(it.unique, type, content, mobile, pics)
            query.enqueue(callback)
        }
    }

    fun upload(picPaths: ArrayList<String>, uploadCallBack: UploadCallBack) {
        var index = 0
        val urlList = ArrayList<String>()
        upload(picPaths[index], object : Callback<HttpResponse<Upload>> {
            override fun onResponse(
                call: Call<HttpResponse<Upload>>,
                response: Response<HttpResponse<Upload>>
            ) {
                if (response.code() == AppConfig.SUCCEED_CODE) {
                    response.body()?.let {
                        urlList.add(it.data.pic)
                        if (index == picPaths.size) {
                            uploadCallBack.onUploadSucceed(urlList)
                        } else {
                            index++
                            upload(picPaths[index], this)
                        }
                    }
                }
            }

            override fun onFailure(call: Call<HttpResponse<Upload>>, t: Throwable) {
            }

        })
    }

    fun upload(picPath: String, callback: Callback<HttpResponse<Upload>>) {
        val convertImageToBase64 = ImageUtils.convertImageToBase64(picPath)
        convertImageToBase64?.let {
            val query = service.upload(convertImageToBase64)
            query.enqueue(callback)
        }
    }

    fun editUser(
        name: String,
        avatar: String,
        birth: String,
        sex: String,
        height: String,
        weight: String,
        callback: Callback<HttpResponse<User>>
    ) {
        user?.let {
            val query = service.editUser(it.unique,name,avatar,birth,sex,height,weight)
            query.enqueue(callback)
        }
    }
    fun setDeviceList(device: Device){
        deviceList.add(device)
    }
    fun getDeviceList():ArrayList<Device>{
        return deviceList
    }
    fun bindingDevice(deviceInfo: DeviceInfo,
        callback: Callback<HttpResponse<String>>
    ) {
//        deviceInfo.serial_name = it.name
//        deviceInfo.serial_mac = it.mac
//        deviceInfo.serial_type = modelNumber
//        deviceInfo.serial_num = modelNumber
//        deviceInfo.serial_version = firmwareRevision
//        deviceInfo.serial_version = hardwareRevision
        user?.let {
            val query = service.bindingDevice(it.unique,deviceInfo.serial_name,deviceInfo.serial_mac,deviceInfo.serial_type,deviceInfo.serial_num,deviceInfo.serial_version,deviceInfo.serial_version)
            query.enqueue(callback)
        }
    }
    fun getBindingDevice(
        callback: Callback<HttpResponse<ArrayList<DeviceInfo>>>
    ) {
        user?.let {
            val query = service.getDeviceList(it.unique)
            query.enqueue(callback)
        }
    }

}